/*
*********************************
*@version: V2.0
*@date: 2023/3/3 11:58
1.登录成功后，进入主界面界面刷新接口
2.数据查询接口
*********************************
*/
package hanlder

import (
	"encoding/json"
	"fmt"
	"groudserver/db"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	"github.com/sirupsen/logrus"
)

// 分页查找查询接口
func (vp *queryHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	//分页查找
	var res RespEx
	var sql string
	var isRes bool
	var response ResponseEx
	if r.Method != "POST" {
		res = GetStatusCodeEx(405)
		isRes = true
	}
	if r.RequestURI == "" {
		res = GetStatusCodeEx(406)
		isRes = true
	}
	if len(r.Header.Get("token")) <= 0 || r.Header.Get("token") == "" {
		res = GetStatusCodeEx(203)
		isRes = true
	} else if len(r.Header.Get("token")) > 0 && r.Header.Get("token") != "" {
		token := r.Header.Get("token")
		sql = "select username, token, createtime from " + Ptv.DataBase.UserInfoTbl + " where token = " + "'" + token + "'"
		res = VerifyToken(sql)
		logrus.Info("查询状态码", res.Code)
		if res.Code != 200 {
			logrus.Error("Token 校验失败")
			isRes = true
		}
		if res.Code == 200 { //如果鉴权成功
			//开启分页查询
			var condition QueryBody
			body, err := ioutil.ReadAll(r.Body)
			if err != nil && err != io.EOF {
				logrus.Error("处理信息 err:", err.Error(), "信息请求处理消息体：", string(body))
				res = GetStatusCodeEx(400)
				isRes = true
			} else {

				sql = "SELECT * from " + Ptv.DataBase.MainTbl
				sqlstr := "SELECT COUNT(*) FROM " + Ptv.DataBase.MainTbl
				if err := json.Unmarshal([]byte(string(body)), &condition); err != nil {
					if len(string(body)) == 0 {
						sql += " ORDER BY id DESC LIMIT  0, 20"
						response = QueryInfo(sql, sqlstr)
						isRes = false
					} else {
						res = GetStatusCodeEx(400)
						isRes = true
					}

				} else {
					//开启分页查找,只包含一个pageIndex字段
					//1.主表查询,实现主界面的查询
					if strings.Contains(string(body), "mid") {
						sql = "SELECT * from " + Ptv.DataBase.SubTbl + " where mid=" + fmt.Sprintf("%d", condition.Mid) + " ORDER BY id DESC"
						logrus.Info("附表数据查询语句sql：", sql)
						res = QueryAlarmInfo(sql)
						isRes = true

					} else {
						if strings.Contains(string(body), "carNum") && condition.CarNum > 0 {
							sql += " where carNum = " + fmt.Sprintf("%d", condition.CarNum)
							sqlstr += " where carNum = " + fmt.Sprintf("%d", condition.CarNum)
						}
						if strings.Contains(string(body), "startTime") && strings.Contains(string(body), "endTime") &&
							condition.StartTime != "" && condition.EndTime != "" {
							local, err := time.LoadLocation("Asia/Shanghai")
							if err != nil {
								local = time.FixedZone("CST", 8*3600)
							}
							startDate, _ := time.ParseInLocation("2006-01-02 15:04:05", condition.StartTime, local)
							endDate, _ := time.ParseInLocation("2006-01-02 15:04:05", condition.EndTime, local)
							if strings.Contains(string(body), "carNum") && condition.CarNum > 0 {
								sql += " and "
								sqlstr += " and "
							} else {
								sql += " where "
								sqlstr += " where"
							}
							sql += " alarmTime BETWEEN ' " + startDate.Format("2006-01-02  15:04:05") + "' AND '" + endDate.Format("2006-01-02  15:04:05") + "' "
							sqlstr += " alarmTime BETWEEN ' " + startDate.Format("2006-01-02  15:04:05") + "' AND '" + endDate.Format("2006-01-02  15:04:05") + "' "

						}
						//先看一下总数是多少页
						numberToltal := db.QueryToltalNumber(sqlstr)
						var page int
						if numberToltal > 0 {
							if numberToltal%20 != 0 {
								page = numberToltal/20 + 1
							} else {
								page = numberToltal / 20
							}
						}
						//如果其中一个没有选择，起始时间是一个月前，终止时间是
						if strings.Contains(string(body), "pageIndex") && condition.PageIndex > 0 && condition.PageIndex <= page {
							//分页查询，不包含其他字段
							sql += " ORDER BY id DESC LIMIT  " + fmt.Sprintf("%d", (condition.PageIndex-1)*20) + "," + " 20"
						}
						if strings.Contains(string(body), "pageIndex") && condition.PageIndex > page {
							//分页查询，不包含其他字段
							sql += " ORDER BY id DESC LIMIT  " + fmt.Sprintf("%d", (page-1)*20) + "," + " 20"

						} else if !strings.Contains(string(body), "pageIndex") && condition.PageIndex < 0 {
							sql += " ORDER BY id DESC LIMIT  0," + " 20"
						}
						logrus.Info("查询数据 sql", sql)
						logrus.Info("查询数据 sqlstr", sqlstr)
						response = QueryInfo(sql, sqlstr)
						isRes = false

					}
				}

			}
		}
	}
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Header().Set("Access-Control-Allow-Origin", "*")
	//跨域头
	w.Header().Set("Access-Control-Allow-Methods", "*")
	//w.Header().Set("Access-Control-Allow-Headers", "Content-Type,XFILENAME,XFILECATEGORY,XFILESIZE")
	w.Header().Set("Access-Control-Allow-Headers", "*")
	if isRes {
		if err := json.NewEncoder(w).Encode(res); err != nil {
			logrus.Fatal(err)
		}
	} else {
		if err := json.NewEncoder(w).Encode(response); err != nil {
			logrus.Fatal(err)
		}

	}

}

// 获取carNum列表
func (pv *getCarListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	var res RespEx
	var sql string
	if r.Method != "GET" {
		res = GetStatusCodeEx(405)
	}
	if r.RequestURI == "" {
		res = GetStatusCodeEx(406)
	}
	if len(r.Header.Get("token")) <= 0 || r.Header.Get("token") == "" {
		res = GetStatusCodeEx(203)
	} else if len(r.Header.Get("token")) > 0 && r.Header.Get("token") != "" {
		token := r.Header.Get("token")
		sql = "select username, token, createtime from " + Ptv.DataBase.UserInfoTbl + " where token = " + "'" + token + "'"
		res = VerifyToken(sql)
		if res.Code != 200 {
			logrus.Error("Token 鉴权失败")
		}
		if res.Code == 200 {
			sql := "SELECT DISTINCT carNum FROM " + Ptv.DataBase.MainTbl + " ORDER BY carNum ASC"
			data, _ := db.GetCarList(sql)
			if len(data) < 0 {
				res = GetStatusCodeEx(404)
			} else {
				res.Code = 200
				res.Data = data
				res.Msg = "success"
			}
		}

	}
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Header().Set("Access-Control-Allow-Origin", "*")
	//跨域头
	w.Header().Set("Access-Control-Allow-Methods", "*")
	w.Header().Set("Access-Control-Allow-Headers", "*")
	if err := json.NewEncoder(w).Encode(res); err != nil {
		logrus.Fatal(err)
	}
}

// Token检验
func VerifyToken(sql string) RespEx {
	var result []*db.UserInfo
	var res RespEx
	var ret bool

	result, ret = db.QueryUserInfo(sql)
	logrus.Println("鉴权校验sql:", sql, "\n ret:", ret)
	logrus.Info("查询数据:", len(result), "ret:", ret)
	if ret == true {
		res = GetStatusCodeEx(200) //token 错误
	}
	if ret != false {
		logrus.Info("鉴权检验成功, Verify Success")
		if len(result) > 0 {
			logrus.Debug("查询数据存在 UserName", result[0].UserName, "Token", result[0].Token, "CreateTime", result[0].CreateTime)
			timesec := time.Now().Unix() //当前的时间戳
			logrus.Info("时间差是：", timesec-result[0].CreateTime, "当前时间戳")
			if timesec-result[0].CreateTime >= MAXAGE {
				//删除用户信息数据库中对应的token
				sql := "delete from " + Ptv.DataBase.UserInfoTbl + " where token = " + "'" + result[0].Token + "'"
				logrus.Info("删除用户信息sql:", sql)
				if db.DeleteDB(sql) {
					res = GetStatusCodeEx(203)
				} else {
					res = GetStatusCodeEx(202)
				}
			}
			if timesec-result[0].CreateTime < MAXAGE { //token还在有效期内
				res = GetStatusCodeEx(200)
			}
		}
	} else {
		logrus.Error("鉴权检验失败, Verify Failed")
		res = GetStatusCodeEx(202)
	}
	return res
}

// 数据查询，主表查询
func QueryInfo(sql, strCout string) ResponseEx {
	logrus.Info("查询条件语句：", sql)
	logrus.Info("数据查询总数语句:", strCout)
	var alarmInfo []*db.AlarmData
	var ret bool
	var res ResponseEx
	alarmInfo, ret = db.QueryAlarmEx(sql)
	if ret != false {
		number := db.QueryToltalNumber(strCout) //计算
		res.Msg = "success"
		res.Code = 200
		res.Data.List = alarmInfo
		res.Data.Total = number

	} else { //查询失败
		res.Msg = "failed"
		res.Code = 404
	}
	return res
}

// 查询数据，查询单个一行数据
func QueryMtlInfo(sql string) []*db.AlarmData {
	var alarmInfo []*db.AlarmData
	var ret bool
	alarmInfo, ret = db.QueryAlarmEx(sql)
	if ret != false {
		return alarmInfo
	} else {
		return nil
	}
}

// 查询数据单个附表，查询单个数据
func QuerySubTblInfo(sql string) []*db.Alarm {
	var alarmInfo []*db.Alarm
	var ret bool
	alarmInfo, ret = db.QueryAlarmInfo(sql)
	if ret != false {
		return alarmInfo
	} else {
		return nil
	}
}

func QueryAlarmInfo(sql string) RespEx {
	logrus.Info("查询语句：", sql)
	var alarmInfo []*db.Alarm
	var ret bool
	var res RespEx
	alarmInfo, ret = db.QueryAlarmInfo(sql)
	if ret != false {
		res.Msg = "success"
		res.Code = 200
		res.Data = alarmInfo

	} else { //查询失败
		res.Msg = "failed"
		res.Code = 404
		res.Data = false
	}
	return res
}
